package state;

import lombok.extern.slf4j.Slf4j;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.LongStream;

@Slf4j
public class ThreadStateDemo {

    public static void main(String[] args) throws Exception {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        final Object lock = new Object();
        final Object lockOther = new Object();
        // 睡5分钟
        executorService.submit(
                () -> {
                    synchronized (lock) {
                        while(true) {
                            try {
                                Long sum = 0L;
                                LongStream.range(1,1000_1000_1L).forEach(
                                        (l)-> sum.equals(l * l)
                                );
                                // 等待1sec
                                Thread.sleep(5 *100L);
                            } catch (InterruptedException e) {
                                throw new RuntimeException(e);
                            }
                        }
                    }
                }
        );

        // 进入block队列
        executorService.submit(
                () -> {
                    synchronized (lock) {
                        try {
                            // 等待3分钟
                            Thread.sleep(3 * 60 *1000L);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
        );

        // 进入wait队列
        executorService.submit(
                () -> {
                    synchronized (lockOther) {
                        try {
                            // 等待5分钟
                            lock.wait(5 * 60 *1000L);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
        );

        executorService.submit(
                () -> {
                    synchronized (lockOther) {

                    }
                }
        );

        Thread t10 = new Thread(
                () -> {
                    while(true) {
                        poolInfo();
                        try {
                            Thread.sleep(1000L);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
        );
        t10.start();
        t10.join();
    }

    public static String poolInfo() {
        ThreadMXBean mx = ManagementFactory.getThreadMXBean();
        // 1. 先拿到 JVM 里全部线程
        long[] ids = mx.getAllThreadIds();
        ThreadInfo[] infos = mx.getThreadInfo(ids, true, true);

        // 2. 过滤出名字符合池命名规则的线程
        //    默认池会给线程起名叫  "pool-N-thread-M"
        StringBuilder builder = new StringBuilder();
        for (ThreadInfo ti : infos) {
            if (ti != null && ti.getThreadName().startsWith("pool")) {
                // NEW/RUNNABLE/BLOCKED/WAITING...
                builder.append(ti.getThreadName())
                        .append(" : ")
                        .append(ti.getThreadState())
                        .append("\n");
            }
        }
        return builder.toString();
    }

}
